#from jili.price import kline
#from jili.trade import simpos
#,PerformanceAnalysis_no,reporthtml
#from jili.trade import active as act
from jili.data.db import tick_dataset_pkl
from jili.core.printlog import print
from jili.price.kline import kline1d,klinenm,kline1m

class ss_frame():
    def __init__(self,config):
        self.calor_layers_bytick=[]
        self.calor_layers_by1mbar=[]
        self.calor_layers_byendday=[]
        self.calor_layers_bybeforeopen=[]
        self.calor_layers_bybeforeclose=[]
        self.d = {"tick":[]}
        self.sss=[]
        self.poss=[]
        """
        d:dict  tick:list,最新的是最后一个，前一个是d["tick"][-2]
        每个bar一个list
        """
        self.data_batch=100
        self.config={}
        self.obj = ""
        self.kline1m=None
        self.klines={}
        self.todayisclosecall={"date":None,"iscall":False}
        self.todayisopencall={"date":None,"iscall":False}
        self.setconfig(config)
    def initpos(self):
        pass
    def setconfig(self,config):
        import copy
        self.config=copy.deepcopy(config)
        """

        Args:
            config:
                obj:str
                sim:
                    start_date:回测开始时间
                    end_date:回测结束时间
                    tick_url:
                    pos:持仓初始化参数；{fund:1000,fee:1}
                    
                act:
                    marketcode:
                    XXX
                kline_period:list kline bar周期；多周期计算使用["1m","5m","1d"],str
                ta:TA指标 dict  {"1m":[{},{}]}
        Returns:nul

        """
        if "obj" not in config.keys():
            raise Exception("请确定策略的交易代码，config中必须有obj")
        else:
            self.obj=config["obj"]
        if "data_batch" in self.config.keys():
            self.data_batch = self.config["data_batch"]
        if "kline_period" in config.keys():
            kline_period=config["kline_period"]
            for i in kline_period:
                bartype=i[-1]
                mn=int(i[:-1])
                if bartype=="d":
                    self.klines[i]=kline1d(self.obj,bars_len=self.data_batch)
                    #self.d[i]=[]
                else:
                    if mn==1:
                        self.kline1m=kline1m(self.obj,bars_len=self.data_batch)
                        self.d["1m"] = self.kline1m.bars
                        self.kline1m.setonbar(self.__on1mbar)
                    else:
                        self.klines[i]=klinenm(self.obj,period=mn,bars_len=self.data_batch)
                        #self.d[i] = []
            if not self.kline1m:
                self.kline1m = kline1m(self.obj,bars_len=self.data_batch)
                self.d["1m"] = self.kline1m.bars
                self.kline1m.setonbar(self.__on1mbar)
        for k,v in self.klines.items():
            self.d[k]=v.bars
            #self.kline1m.setonbar(v.onbar)
        if "ta" in config.keys():
            tas=self.config["ta"]
            if "1m" in tas.keys():
                for i in tas["1m"]:
                    self.kline1m.add_ta(i)
            for k,taargs in tas.items():
                if k in self.klines.keys():
                    for i in taargs:
                        self.klines[k].add_ta(i)
    def __ontick(self,t):
        tk=t["timekey"]
        date0 = tk.date()
        if self.kline1m.checktime(tk):
            self.d["tick"].append(t)
            if len(self.d["tick"])>self.data_batch:
                self.d["tick"].pop(0)
            self.kline1m.ontick(t)
            for i in self.calor_layers_bytick:
                i(self.d)
            for i in self.sss:
                i.ontick(self.d)
            if tk.hour ==14 and tk.second==59:
                for i in self.calor_layers_bybeforeclose:
                    i(self.d)
                for i in self.sss:
                    i.onbeforeclose(self.d)
        elif tk.hour>=18 and tk.hour <9:
            if self.todayisclosecall["date"]!=date0:
                for i in self.calor_layers_bybeforeopen:
                    i(t)
                for i in self.sss:
                    i.onbeforeopen(self.d)
                self.todayisclosecall["date"]=date0
                self.todayisclosecall["iscall"]=True
            elif not self.todayisclosecall["iscall"]:
                for i in self.calor_layers_bybeforeopen:
                    i(t)
                for i in self.sss:
                    i.onbeforeopen(self.d)
                self.todayisclosecall["date"]=date0
                self.todayisclosecall["iscall"]=True
        elif tk.hour>=15 and tk.hour <18:
            date0=tk.date()
            if self.todayisopencall["date"]!=date0:
                for i in self.calor_layers_byendday:
                    i(t)
                for i in self.sss:
                    i.onendday(self.d)
                self.todayisopencall["date"]=date0
                self.todayisopencall["iscall"]=True
            elif not self.todayisopencall["iscall"]:
                for i in self.calor_layers_byendday:
                    i(t)
                for i in self.sss:
                    i.onendday(self.d)
                self.todayisopencall["date"]=date0
                self.todayisopencall["iscall"]=True
    def __on1mbar(self,b):
        for v in self.klines.values():
            v.onbar(b)
        for i in self.calor_layers_by1mbar:
            i(self.d)
        for i in self.sss:
            i.on1mbar(self.d)
    def addss(self,ss):
        self.sss.append(ss)
    def addlayer_bybeforeopen(self,calor):
        self.calor_layers_bybeforeopen.append(calor)
    def addlayer_bybeforeclose(self, calor):
        self.calor_layers_bybeforeclose.append(calor)
    def addlayer_byendday(self,calor):
        self.calor_layers_byendday.append(calor)
    def addlayer_bytick(self,calor,):
        self.calor_layers_bytick.append(calor)
    def addlayer_by1mbar(self,calor,):
        self.calor_layers_by1mbar.append(calor)
    def run(self,model="sim"):
        if model=="sim":
            if "obj" not in self.config.keys():
                raise Exception("请确定策略的交易代码，config中必须有obj")
            else:
                if "sim" in self.config.keys():
                    simarg=self.config["sim"]
                    start_date=None
                    if "start_date" in simarg.keys():
                        start_date=simarg["start_date"]
                    end_date = None
                    if "end_date" in simarg.keys():
                        end_date = simarg["end_date"]
                    if "tick_url" not in simarg.keys():
                        tick_iter=tick_dataset_pkl(self.obj,start_date,end_date)
                    else:
                        tick_iter = tick_dataset_pkl(self.obj, start_date, end_date,simarg["tick_url"])
                else:
                    tick_iter = tick_dataset_pkl(self.obj)
                for t in tick_iter:
                    # print(t)
                    self.__ontick(t)
            print("ss run end")
        else:
            from jili.price import tick
            mk = ""
            if "act" in self.config.keys():
                if "marketcode" in self.config["act"].keys():
                    mk=self.config["act"]["marketcode"]
                rst=tick.subtick(self.obj,mkcode=mk,ontick=self.__ontick)
                print("subtick:",self.obj,mk,rst)
            else:
                rst = tick.subtick(self.obj, mkcode=mk, ontick=self.__ontick)
                print("not act config subtick:", self.obj, mk, rst)
if __name__ == "__main__":
    import datetime
    print(datetime.datetime.now())
    c={
        "obj":"rb1810",
        "sim":{
            "start_date":"20180308",
            "end_date":"20180812"
        },
        "kline_period":["1m","5m","30m","1d"],
        "ta":{
            "1m":[
                {"cmd": "MACD", "out": ["macd", "macdsignal", "macdhist"], "arg": {"fastperiod": 12, "slowperiod": 26, "signalperiod": 9}, "batch": 34},
                {"cmd": "EMA", "out": ["ema5"], "arg": {"timeperiod": 5}, "batch": 5},
                {"cmd": "EMA", "out": ["ema10"], "arg": {"timeperiod": 10}, "batch": 10},
                {"cmd": "EMA", "out": ["ema20"], "arg": {"timeperiod": 20}, "batch": 20},
                {"cmd": "KDJ", "out": ["K", "D", "J"], "arg": {"timeperiod": 9, "m1": 3, "m2": 3}, "batch": 13},
                {"cmd": "ATR", "out": ["atr"], "arg": {"timeperiod": 14}, "batch": 15},
                {"cmd": "RSI", "out": ["rsi"], "arg": {"timeperiod": 14}, "batch": 15},
            ],
            "5m": [
                {"cmd": "MACD", "out": ["macd", "macdsignal", "macdhist"], "arg": {"fastperiod": 12, "slowperiod": 26, "signalperiod": 9}, "batch": 34},
                {"cmd": "EMA", "out": ["ema5"], "arg": {"timeperiod": 5}, "batch": 5},
                {"cmd": "EMA", "out": ["ema10"], "arg": {"timeperiod": 10}, "batch": 10},
                {"cmd": "EMA", "out": ["ema20"], "arg": {"timeperiod": 20}, "batch": 20},
                {"cmd": "KDJ", "out": ["K", "D", "J"], "arg": {"timeperiod": 9, "m1": 3, "m2": 3}, "batch": 13},
                {"cmd": "ATR", "out": ["atr"], "arg": {"timeperiod": 14}, "batch": 15},
                {"cmd": "RSI", "out": ["rsi"], "arg": {"timeperiod": 14}, "batch": 15},
            ],
            "30m": [
                {"cmd": "MACD", "out": ["macd", "macdsignal", "macdhist"], "arg": {"fastperiod": 12, "slowperiod": 26, "signalperiod": 9}, "batch": 34},
                {"cmd": "EMA", "out": ["ema5"], "arg": {"timeperiod": 5}, "batch": 5},
                {"cmd": "EMA", "out": ["ema10"], "arg": {"timeperiod": 10}, "batch": 10},
                {"cmd": "EMA", "out": ["ema20"], "arg": {"timeperiod": 20}, "batch": 20},
                {"cmd": "KDJ", "out": ["K", "D", "J"], "arg": {"timeperiod": 9, "m1": 3, "m2": 3}, "batch": 13},
                {"cmd": "ATR", "out": ["atr"], "arg": {"timeperiod": 14}, "batch": 15},
                {"cmd": "RSI", "out": ["rsi"], "arg": {"timeperiod": 14}, "batch": 15},
            ],
            "1d": [
                {"cmd": "MACD", "out": ["macd", "macdsignal", "macdhist"], "arg": {"fastperiod": 12, "slowperiod": 26, "signalperiod": 9}, "batch": 34},
                {"cmd": "EMA", "out": ["ema5"], "arg": {"timeperiod": 5}, "batch": 5},
                {"cmd": "EMA", "out": ["ema10"], "arg": {"timeperiod": 10}, "batch": 10},
                {"cmd": "EMA", "out": ["ema20"], "arg": {"timeperiod": 20}, "batch": 20},
                {"cmd": "KDJ", "out": ["K", "D", "J"], "arg": {"timeperiod": 9, "m1": 3, "m2": 3}, "batch": 13},
                {"cmd": "ATR", "out": ["atr"], "arg": {"timeperiod": 14}, "batch": 15},
                {"cmd": "RSI", "out": ["rsi"], "arg": {"timeperiod": 14}, "batch": 15},
            ]
        }
    }
    ss=ss_frame(c)
    n=0
    print(datetime.datetime.now())
    ss.run()
    print(datetime.datetime.now())